package com.sunop.judge.util;

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.github.dockerjava.api.DockerClient;
import com.github.dockerjava.api.command.ExecCreateCmdResponse;
import com.github.dockerjava.api.command.InspectExecResponse;
import com.github.dockerjava.core.command.ExecStartResultCallback;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.http.HttpHeaders;
import java.io.ByteArrayOutputStream;
import org.springframework.http.MediaType;
import org.springframework.web.client.RestTemplate;

@Component
@AllArgsConstructor
@Slf4j
public class DockerUtil {

    private final DockerClient dockerClient;
    private final RestTemplate restTemplate;

    public static final String cinFiles = "/tmp/sandbox/";
    /**
     * 在 Docker 容器中执行命令
     *
     * @param containerId 容器 ID
     * @param command     要执行的命令
     * @return 命令执行结果
     */
    public int executeCommand(String containerId, String command) {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        ByteArrayOutputStream errorStream = new ByteArrayOutputStream();

        try {
            // 创建执行命令
            ExecCreateCmdResponse execCmd = dockerClient.execCreateCmd(containerId)
                    .withCmd("sh", "-c", command)
                    .withAttachStdout(true)
                    .withAttachStderr(true)
                    .exec();

            // 执行命令并捕获输出
            dockerClient.execStartCmd(execCmd.getId())
                    .exec(new ExecStartResultCallback(outputStream, errorStream))
                    .awaitCompletion();
            log.info("命令执行结果: " + outputStream.toString());
            log.info("命令执行错误输出: " + errorStream.toString());

            // 检查命令执行状态
            InspectExecResponse inspectExecResponse = dockerClient.inspectExecCmd(execCmd.getId()).exec();
            log.info("命令执行状态: " + inspectExecResponse.toString());

            // 返回退出码
            return inspectExecResponse.getExitCode();
        } catch (InterruptedException e) {
            throw new RuntimeException("执行命令时发生错误", e);
        }
    }

    /**
     * 修改 Docker 容器中的文件
     *
     * @param filePath    文件路径
     * @param content     文件内容
     */
    public void modifyFileInput(String containerId,String filePath, String content) {
        try {
            // 提取目录路径
            String directoryPath = filePath.substring(0, filePath.lastIndexOf("/"));
            log.info("创建目录: " + directoryPath);

            String checkDirCommand = "[ -d \"" + directoryPath + "\" ]";
            int exitCode = executeCommand(containerId, checkDirCommand);

            // 根据退出码判断目录是否存在(0 表示目录存在,1 表示目录不存在)
            boolean dirExists =(exitCode == 1);

            // 如果目录不存在，则创建
            if (dirExists) {
                String mkdirCommand = "mkdir -p " + directoryPath;
                log.info("执行命令: " + mkdirCommand);
                executeCommand(containerId, mkdirCommand);
            } else {
                log.info("目录已存在，跳过创建: " + directoryPath);
            }

            // 使用 cat 命令写入文件内容
            String command = "cat <<EOF > " + filePath + "\n" + content + "\nEOF";
            log.info("执行命令: " + command);
            executeCommand(containerId, command);

            log.info("文件已修改: " + filePath);
        } catch (Exception e) {
            log.error("修改文件失败: " + filePath, e);
            throw new RuntimeException("修改文件失败", e);
        }
    }


    public JSONArray sandJudge(String language, JSONObject jsonObject) {
        log.info("sandJudge: {}", jsonObject);
        // 获取目标 URL
        String url = getTargetUrl(language);
        // 设置请求头
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);

        // 创建 HttpEntity，包含 JSON 对象和请求头
        HttpEntity<String> request = new HttpEntity<>(JSONUtil.toJsonStr(jsonObject), headers);

        // 发送 POST 请求
        try {
            log.info("请求参数: {}", jsonObject);
            ResponseEntity<String> response = restTemplate.postForEntity(url, request, String.class);
            log.info("响应: {}", response);
            return JSONUtil.parseArray(response.getBody());
        } catch (Exception e) {
            log.error("请求失败: {}", e.getMessage());
        }
        return null;
    }

    /**
     * 根据语言获取目标 URL
     *
     * @param language 编程语言
     * @return 目标 URL，如果不支持则返回 null
     */
    private String getTargetUrl(String language) {
        String baseUrl = "http://192.168.150.103:";
        switch (language) {
            case "java":
                return baseUrl + "5070/run";
            case "python":
                return baseUrl + "5071/run";
            case "cpp":
                return baseUrl + "5050/run";
            default:
                return null;
        }
    }

    public String getContainId(String language){
        switch (language) {
            case "java":
                return "836298390fea";
            case "python":
                return "43b74615c652";
            case "cpp":
                return "59ed90b2c236";
            default:
                return null;
        }
    }
}

